package java学习.第17章_反射机制;

import java.lang.reflect.Constructor;
import java.util.Random;
/**
 * 针对核心源码的 api ，内部私有的结构在 jdk17 中就不可通过反射调用了
 */
public class H_反射动态性的体现 {

    public static void main(String[] args) throws Exception {
//        newInstanceTest();

        for (int i = 0; i < 10; i++) {
            int num = new Random().nextInt(5);//0,1,2,3
            String classPath = "";
            switch (num) {
                case 0:
                    classPath = "java.util.Date";
                    break;
                case 1:
                    classPath = "java.lang.Object";
                    break;
                case 2:
                case 4:
                    classPath = "java学习.第17章_反射机制.FS";
                    break;
                case 3:
                    classPath = "java.sql.Date";
                    break;
            }
            try {
                Object[] a =null;
                if(num==2){
                    a=new Object[2];
                    a[0]=int.class;
                    a[1]=5;
                }else if(num==3){
                    a=new Object[2];
                    a[0]=long.class;
                    a[1]=System.currentTimeMillis();
                }else if(num==4){
                    a=new Object[4];
                    a[0]=String.class;
                    a[1]=int.class;
                    a[2]="我指定的";
                    a[3]=5;
                }
                Object obj = getInstance(classPath,a);
                System.out.println(obj);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    public static Object getInstance(String classPath,Object ... objects) throws Exception {
        Class clazz =  Class.forName(classPath);//for Name  名副其实
        if(objects == null){
            Object o = clazz.newInstance();
            o = clazz.getDeclaredConstructor().newInstance();//推荐使用

            return o;//classPath这个类必须有空参构造器 jdk 9以废弃
        }
        int k = objects.length>>1;
        Class<?>[] classes1= new Class<?>[k];
        Object[] objects2= new Object[k];
        for (int i = 0; i < k; i++) {
            classes1[i]= (Class<?>) objects[i];
            objects2[i]= objects[k+i];
        }
        Constructor cons = clazz.getDeclaredConstructor(classes1);//Declared  加这个   可以获得私有的
        cons.setAccessible(true);//保证可访问   使私有的可访问
        return cons.newInstance(objects2);
    }
    //发挥此路径的的类
    public static <T> T getInstance(String classPass) throws Exception{
        Class<?> aClass = Class.forName(classPass);
        Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        return (T) declaredConstructor.newInstance();
    }
}
